package crontab

import (
	"awesomeTask/system/kernel"
	"github.com/robfig/cron"
	"sync"
)

//秒(Seconds)	是	0-59	* / , -
//分(Minutes)	是	0-59	* / , -
//时(Hours)	是	0-23	* / , -
//日(Day of month)	是	1-31	* / , – ?
//月(Month)	是	1-12 or JAN-DEC	* / , -
//星期(Day of week)	否	0-6 or SUM-SAT	* / , – ?
//1 、星号(*) 表示 cron 表达式能匹配该字段的所有值。如在第5个字段使用星号(month)，表示每个月
//
//2、斜线(/) 表示增长间隔，如第1个字段(minutes) 值是 3-59/15，表示每小时的第3分钟开始执行一次，之后每隔 15 分钟执行一次（即 3、18、33、48 这些时间点执行），这里也可以表示为：3/15
//
//3、逗号(,) 用于枚举值，如第6个字段值是 MON,WED,FRI，表示 星期一、三、五 执行
//
//4、连字号(-) 表示一个范围，如第3个字段的值为 9-17 表示 9am 到 5pm 直接每个小时（包括9和17）
//
//5、问号(?) 只用于日(Day of month)和星期(Day of week)，\表示不指定值，可以用于代替 *
//————————————————
var cronSyncMap sync.Map

type CronManagerInterface interface {
	AddTask(taskId string, callBack func(), crontabRegx string, remark string) bool
	RemoveTask(taskId string) bool
	GetTasks() map[string]Task
	GetTaskByTaskId(taskId string) (Task, bool)
	GetTaskNum() int
}

type CronManager struct {
}

type Task struct {
	TaskId       string
	callBack     func()
	crontabRegx  string
	remark       string
	cronInstance *cron.Cron
}

func (CronManager CronManager) GetTaskByTaskId(taskId string) (Task, bool) {
	data, ok := cronSyncMap.Load(taskId)
	if !ok {
		return Task{}, false
	}
	return data.(Task), true
}

func (CronManager CronManager) AddTask(taskId string, callBack func(), crontabRegx string, remark string) bool {
	if _, ok := CronManager.GetTaskByTaskId(taskId); ok {
		return false
	}
	var cronInstance *cron.Cron = cron.New()
	task := Task{
		TaskId:       taskId,
		callBack:     callBack,
		crontabRegx:  crontabRegx,
		remark:       remark,
		cronInstance: cronInstance,
	}
	err := cronInstance.AddFunc(task.crontabRegx, task.callBack)
	if err != nil {
		return false
	}
	cronInstance.Start()
	cronSyncMap.Store(taskId, task)
	return true
}
func (CronManager CronManager) RemoveTask(taskId string) bool {
	taskInfo, ok := CronManager.GetTaskByTaskId(taskId)
	if !ok {
		return false
	}
	taskInfo.cronInstance.Stop()
	cronSyncMap.Delete(taskInfo.TaskId)
	return true
}
func (CronManager CronManager) GetTasks() map[string]Task {
	res := map[string]Task{}
	cronSyncMap.Range(func(key, value interface{}) bool {
		res[key.(string)] = value.(Task)
		return true
	})
	return res
}
func (CronManager CronManager) GetTaskNum() int {
	num := 0
	cronSyncMap.Range(func(key, value interface{}) bool {
		num++
		return true
	})
	return num
}
func GetCronManager() CronManagerInterface {
	instance := kernel.GetIocInstance()
	return instance.GetInstanceOrCreate("mainCron").(CronManagerInterface)
}
